/*
 * @Author: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @Date: 2025-07-01 14:11:41
 * @LastEditors: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @LastEditTime: 2025-09-12 14:19:19
 * @FilePath: \keep_motion_api\models\menu\admin.model.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const { escapeRegex } = require('@/utils');
const { generateToken } = require('@/middleWares/auth/jwt.js');

// 管理员模型
const adminSchema = new Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  nickname: { type: String, required: true },
  role: { 
    type: Schema.Types.ObjectId, 
    ref: 'Role',
    required: true 
  },
  status: { type: Boolean, default: true },
  last_login: Date
});

// 查询字典类型
adminSchema.statics.getAdmin = async function (username = '', role = '', offset = 0, limit = 10) {
  try {
    const query = {};
    if (username) {
      const escapedName = escapeRegex(username);
      query.username = { $regex: escapedName, $options: 'i' };  
    }
    if(role) {
      const { Role } = require('./');
      const roleData = await Role.findOne({code: role});
      query.role = roleData._id;
    }
    // 先统计符合条件的记录总数
    const total = await this.countDocuments(query);
    // 再进行分页查询
    const rows = await this.aggregate([
      { $match: query },                   // 匹配查询条件
      { $skip: Number(offset) },           // 分页跳过
      { $limit: Number(limit) },           // 分页限制
      // 关联查询（相当于 populate）
      { $lookup: {
          from: 'roles',               // 关联的集合名（通常是模型名小写复数）
          localField: 'role',           // 本地关联字段
          foreignField: '_id',             // 关联集合的匹配字段
          as: 'roleInfo'                   // 临时存储关联数据的字段
        }
      },
      { $unwind: '$roleInfo' },            // 展开数组（如果是一对一关系）
      // 投影（展平字段 + 筛选）
      { $project: {
          // 保留原文档字段
          _id: 1, username: 1, password: 1, status: 1, last_login: 1, nickname: 1,
          // 展平关联字段到顶层
          role: '$roleInfo.code',     // 直接映射嵌套字段到顶层
          role_name: '$roleInfo.name',     // 直接映射嵌套字段到顶层
          // 如需保留原type_id可添加: type_id: '$typeInfo._id'
        }
      }
    ]);
    return { rows, total };
  } catch (error) {
    throw error;
  }
}

// 新增管理员
adminSchema.statics.createAdmin = async function (username, password, role, nickname) {
  try {
    // 检查用户名是否已存在
    const existingAdmin = await this.findOne({ username });
    if (existingAdmin) {
      throw new Error('用户名已存在');
    }
    const { Role } = require('./');
    // 检查角色是否存在
    const roleData = await Role.findOne({code: role});
    const admin = new this({username, password, role: roleData._id, nickname});
    await admin.save();
    return admin;
  } catch (error) {
    throw error;
  }
}
// 更新管理员
adminSchema.statics.updateAdmin = async function (adminId, username, password, role, nickname) {
  try {
    const { Role } = require('./');
    // 检查角色是否存在
    const roleData = await Role.findOne({code: role});
    const admin = await this.findByIdAndUpdate(adminId, { username, password, role: roleData._id, nickname }, { new: true });
    return admin;
  } catch (error) {
    throw error;
  }
}
// 禁用管理员
adminSchema.statics.updateAdminStatus = async function (adminId, status) {
  try {
    const admin = await this.findByIdAndUpdate(adminId, { status }, { new: true });
    return admin;
  } catch (error) {
    throw error;
  }
}
// 管理员登录
adminSchema.statics.login = async function (username, password) {
  try {
    const admin = await this.findOne({ username });
    if (!admin) {
      throw new Error('管理员不存在');
    }
    if (admin.password !== password) {
      throw new Error('密码错误');
    }
    // 检查管理员状态
    if (!admin.status) {
      throw new Error('管理员已被禁用');
    }
    // 更新最后登录时间
    admin.last_login = Date.now();
    await this.findByIdAndUpdate(admin._id, admin);
    const { Role } = require('./');
    const roles = await Role.findById(admin.role);
    const token = generateToken({ userId: admin._id, role: roles.code });
    const userInfo = {
      token,
      nickname: admin.nickname,
      role: roles.code,
      role_name: roles.name,
    };
    return userInfo;
  } catch (error) {
    throw error;
  }
}
module.exports = mongoose.model('Admin', adminSchema);
